#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>

#include "cfd-ptrace.h"
#include "cfd-filter.h"
#include "cfd-mmap.h"

void __usage(const char * arg0)
{
    printf("Usage: %s pid /path/code [-s /path/stack] [-f filter] [-F \"filter args\"]\n"
           , arg0
           );

    exit(1);
}

int main(int argc, char *argv[])
{
    if (argc < 3)
    {
        __usage(argv[0]);
    }

    int rval = 1;

    pid_t pid = strtol(argv[1], NULL, 10);
    void * _code   = argv[2];
    void * _stack  = NULL;
    void * _filter = NULL;

    struct filter *filter = NULL;
    const char * _filter_args = NULL;

    printf("pid: %d\n", pid);

    /* Parse options */
    char opt;
    while ((opt = getopt(argc, argv, "s:f:F:h")) != -1) {
        switch (opt) {
            case 's':
                _stack = optarg;
                break;

            case 'f':
                _filter = optarg;
                break;

            case 'F':
                _filter_args = optarg;
                break;

            case 'h': /* '?' */
                __usage(argv[0]);
        }
    }


    /* Setup data */

    struct mfile * text = NULL;
    struct mfile * data = NULL;

    text = mmap_file(_code
                     , 0
                     , O_RDONLY
                     );

    if (NULL == text)
        goto lbEnd;


    if (_stack)
    {
        data = mmap_file(_stack
                         , 0
                         , O_RDONLY
                         );
        if (NULL == data)
            goto lbEnd;
    }

    if (_filter)
    {
        filter = open_filter(_filter
                             , _filter_args
                             );
    }

    rval = run_text(pid
                    , text->memory
                    , text->memory_size
                    , data
                      ? data->memory
                      : NULL
                    , data
                      ? data->memory_size
                      : 0
                    , filter
                    , NULL
                    );

    printf("RVAL: %d\n", rval);

    if (filter)
        close_filter(filter);

  lbEnd:

    munmap_file(text);
    munmap_file(data);

    return rval;
}

